home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok46.lha
/
Programme
/
SternSimulation.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
27KB
|
883 lines
(*
* -------------------------------------------------------------------------
*
* :Program. SternSimulation
* :Contents. Simulation von Gravitationskräften.
* :Author. Reiner Nix
* :Address. Geranienhof 2, 5000 Köln 71 Seeberg
* :Copyright. Public Domain
* :Language. Modula-2
* :Translator. M2Amiga A-L V3.3d
* :History. V1.0 21.11.90
* :Imports. IntuitionTools, siehe diese Diskette
* :Imports. AmigaGraphik, siehe diese Diskette
* :Imports. IntuitionTools, siehe diese Diskette
*
* -------------------------------------------------------------------------
*)
MODULE SternSimulation;
FROM SYSTEM IMPORT ADR, LONGSET;
FROM Arts IMPORT Assert, TermProcedure, Requester;
FROM Exec IMPORT UByte, Byte,
Wait, GetMsg, ReplyMsg;
FROM Layers IMPORT ScrollLayer;
FROM Graphics IMPORT FontStyles, FontStyleSet,
FontFlags, FontFlagSet,
TextFontPtr, BitMapPtr,
TextAttr;
FROM Intuition IMPORT customScreen, gzzGadget, maxBody,
IDCMPFlags, IDCMPFlagSet,
WindowFlags, WindowFlagSet,
GadgetFlags, GadgetFlagSet,
PropInfoFlags, PropInfoFlagSet,
ActivationFlags, ActivationFlagSet,
WindowPtr, ScreenPtr, IntuiMessagePtr,
NewScreen, NewWindow, IntuiMessage,
AddGadget, RefreshGList,
WindowToBack, WindowToFront,
OpenWorkBench, CloseWorkBench;
FROM IntuitionTools IMPORT GraphMode, XrelBreite, YrelHoehe,
relBreite, relHoehe,
initNewScreen, initNewWindow, initTextAttr,
initPropInfo, openBitMap,
selectGadget, deselectGadget,
enableGadgets, disableGadgets,
refreshOneGadget;
FROM AmigaGraphik IMPORT OpenScreen, CloseScreen, UseScreen,
OpenWindow,CloseWindow, UseWindow,
OpenFont, CloseFont, UseFont,
SetColourReg, SetAPen, SetBPen,
Move, WriteString, WriteCard, WriteInt,
WritePixel, FillRectangle;
FROM IntuitionObjekte IMPORT ObjektTyp, BooleanTyp, ObjektEreignis,
ObjektPtr,
ObjektAktion, PruefeEingabe,
setzeTextFarbe, setzeLinienFarbe,
setzeRandFarbe, setzeEingabeFarbe,
setzeAusrichtung, setzeGadgetTyp,
setzeHPosition, setzeVPosition,
erzeugeBooleanObjekt,
erzeugeTextObjekt,
erzeugeRealObjekt,
erzeugeHPropObjekt, erzeugeVPropObjekt,
findeObjekt, verbindeObjekte,
verarbeiteNachricht,
frageGadget, frageObjektNr, EingabeOk,
aenderInfoSatz, erneuerObjekte,
frageHPosition, frageVPosition,
loescheAlleObjekte;
FROM MathLib0 IMPORT sqrt;
CONST maxName =21;
maxKoerper =12;
xSchirmMax =640;
ySchirmMax =256;
superBreite =704;
superHoehe =512;
SchirmTitel ="Sternsimulation V1.0";
EingabeTitel ="Eingabefenster";
AusgabeTitel ="Ausgabefenster";
keinSchirm ="Schlag mich! Konnte Schirm nicht öffnen.";
keinFenster ="Tritt mich! Konnte Fenster nicht öffnen.";
keineBitMap ="keine BitMap DA";
NameID = 1;
PosID = 2;
aID = 5;
vID = 8;
MasseID =11;
ZeitID =12;
ZoomID =13;
FarbeID =13; (* Farbe+1 .. FarbeID+maxKoerper *)
SimuID =1000;
LoeschenID =1001;
NeuID =1004;
KoerperID =2004;
AktivID =2024;
HochID = 1;
BreitID = 2;
g =6.67E-11;
TYPE TName =ARRAY [1..maxName+2] OF CHAR;
Vektor =RECORD x, y, z :REAL
END;
TKoerper =RECORD Name :TName;
Position,
AltPosition,
Geschwindigkeit,
Beschleunigung :Vektor;
Masse :REAL;
Farbe :INTEGER;
Aktiv :BOOLEAN
END;
VAR Bildschirm :ScreenPtr;
EingabeFenster,
AusgabeFenster :WindowPtr;
Times18, Topaz8 :TextFontPtr;
Koerper :ARRAY [0..maxKoerper] OF TKoerper;
Planet :INTEGER;
t, Zoom, altZoom :REAL;
rechnenAn :BOOLEAN;
xAlt, yAlt :CARDINAL;
PROCEDURE CleanUp;
BEGIN
loescheAlleObjekte (EingabeFenster);
loescheAlleObjekte (AusgabeFenster);
IF Times18 # Topaz8 THEN
CloseFont (Times18)
END;
CloseFont (Topaz8);
CloseWindow (AusgabeFenster);
CloseWindow (EingabeFenster);
CloseScreen (Bildschirm);
IF OpenWorkBench () # NIL THEN (* Ergebnis unnötig *)
END
END CleanUp;
PROCEDURE LoescheAusgabe;
BEGIN
UseWindow (AusgabeFenster);
SetAPen (14);
FillRectangle (0,0, 3000,3000)
END LoescheAusgabe;
PROCEDURE LoescheAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
BEGIN
LoescheAusgabe
END LoescheAktion;
PROCEDURE SystemAnpassen;
(* Aufgabe: Bildschirm öffnen, Farben einstellen,
* EingabeFenster und AusgabeFenster öffnen
*)
VAR neuSchirm :NewScreen;
neuFenster :NewWindow;
BitMap :BitMapPtr;
Attribute :TextAttr;
BEGIN
Bildschirm := NIL;
EingabeFenster := NIL;
AusgabeFenster := NIL;
Times18 := NIL;
Topaz8 := NIL;
TermProcedure (CleanUp);
IF CloseWorkBench () THEN (* Ergebnis unnötig *)
END;
initNewScreen (neuSchirm,
0,0, xSchirmMax,ySchirmMax,
4, 1,14, HiRes,
customScreen,
NIL, (* Font *)
ADR (SchirmTitel));
Bildschirm := OpenScreen (neuSchirm);
Assert (Bildschirm # NIL, ADR (keinSchirm));
UseScreen (Bildschirm);
SetColourReg ( 0, 0666H);
SetColourReg ( 1, 0FFFH);
SetColourReg ( 2, 0B60H);
SetColourReg ( 3, 0480H);
SetColourReg ( 4, 0FF0H);
SetColourReg ( 5, 0851H);
SetColourReg ( 6, 0988H);
SetColourReg ( 7, 000FH);
SetColourReg ( 8, 0F00H);
SetColourReg ( 9, 0F0FH);
SetColourReg (10, 0EA9H);
SetColourReg (11, 0966H);
SetColourReg (12, 0357H);
SetColourReg (13, 0868H);
SetColourReg (14, 0000H);
SetColourReg (15, 0F80H);
BitMap := openBitMap (superBreite, superHoehe, 4);
Assert (BitMap # NIL, ADR (keineBitMap));
initNewWindow (neuFenster,
240,10, 400,246,
14, 1,
IDCMPFlagSet {newSize, sizeVerify},
WindowFlagSet {windowDepth, windowSizing, windowDrag,
sizeBRight, sizeBBottom,
superBitMap, gimmeZeroZero, noCareRefresh},
NIL, NIL,
ADR (AusgabeTitel),
Bildschirm,
BitMap,
170,50, -1,-1,
customScreen);
AusgabeFenster := OpenWindow (neuFenster);
Assert (AusgabeFenster # NIL, ADR (keinFenster));
initNewWindow (neuFenster,
0,10, 640,246,
14, 1,
IDCMPFlagSet {closeWindow},
WindowFlagSet {windowDepth, windowClose, noCareRefresh},
NIL, (* kein Gadget *)
NIL, (* keine CheckMark *)
ADR (EingabeTitel),
Bildschirm,
NIL,
0,0, 0,0, (* min, max *)
customScreen);
EingabeFenster := OpenWindow (neuFenster);
Assert (EingabeFenster # NIL, ADR (keinFenster));
LoescheAusgabe;
initTextAttr (Attribute,
ADR ("topaz.font"), 8, FontStyleSet {}, FontFlagSet {});
Topaz8 := OpenFont (Attribute);
initTextAttr (Attribute,
ADR ("times.font"), 18, FontStyleSet {}, FontFlagSet {});
Times18 := OpenFont (Attribute);
IF Times18 = NIL THEN
Assert (Requester ( ADR (SchirmTitel),
ADR ("Zeichensatz Times.18 nicht gefunden"),
ADR ("nimm Topaz.8"), ADR ("Programm abbrechen")),
ADR ("Programmstop!"));
Times18 := Topaz8
END
END SystemAnpassen;
PROCEDURE WerteEinstellen;
VAR i :CARDINAL;
BEGIN
WITH Koerper[1] DO
Name := "Sonne ";
Position.x := 0.0;
Position.y := 0.0;
Position.z := 0.0;
Geschwindigkeit := Position;
Beschleunigung := Position;
Masse := 1.985E30;
Farbe := 4;
END;
FOR i := 2 TO maxKoerper DO
Koerper[i] := Koerper[1];
Koerper[i].Farbe := i+3
END;
WITH Koerper[2] DO
Name := "Merkur ";
Position.y := 5.79E10;
Geschwindigkeit.x := 4.79E4;
Masse := 3.169E23
END;
WITH Koerper[3] DO
Name := "Venus ";
Position.y := 1.08E11;
Geschwindigkeit.x := 3.50E4;
Masse := 4.873E24
END;
WITH Koerper[4] DO
Name := "Erde ";
Position.y := 1.496E11;
Geschwindigkeit.x := 2.978E4;
Masse := 5.979E24
END;
WITH Koerper[5] DO
Name := "Mars ";
Position.y := 2.279E11;
Geschwindigkeit.x := 2.41E4;
Masse := 6.398E23
END;
WITH Koerper[6] DO
Name := "Jupiter (Jupp) ";
Position.y := 7.78E11;
Geschwindigkeit.x := 1.31E4;
Masse := 1.901E27
END;
WITH Koerper[7] DO
Name := "Saturn ";
Position.y := 1.427E12;
Geschwindigkeit.x := 9.6E3;
Masse := 5.693E26
END;
WITH Koerper[8] DO
Name := "Uranus ";
Position.y := 2.870E12;
Geschwindigkeit.x := 6.8E3;
Masse := 8.699E25
END;
WITH Koerper[9] DO
Name := "Neptun ";
Position.y := 4.496E12;
Geschwindigkeit.x := 5.4E3;
Masse := 1.030E26;
END;
WITH Koerper[10] DO
Name := "Pluto ";
Position.y := 5.946E12;
Geschwindigkeit.x := 4.7E3;
Masse := 2.319E22
END;
FOR i := 11 TO maxKoerper DO
WITH Koerper[i] DO
Name := " ";
Masse := 0.0
END
END;
FOR i := 1 TO maxKoerper DO
WITH Koerper[i] DO
AltPosition := Position;
Aktiv := (Masse # 0.0)
END
END;
Planet := 4;
Koerper[0] := Koerper[Planet];
t := 86400.0;
Zoom := 2.0E9;
altZoom := Zoom
END WerteEinstellen;
PROCEDURE StartStopAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
BEGIN
rechnenAn := NOT rechnenAn;
IF rechnenAn THEN
Koerper[0].Aktiv := Koerper[Planet].Aktiv;
Koerper[Planet] := Koerper[0];
aenderInfoSatz (findeObjekt (EingabeFenster, Planet+KoerperID),
Koerper[Planet].Name);
objekt := findeObjekt (EingabeFenster, SimuID);
aenderInfoSatz (objekt , " Halt an! ");
selectGadget (EingabeFenster, frageGadget (objekt));
objekt := findeObjekt (AusgabeFenster, SimuID);
aenderInfoSatz (objekt , " Halt an! ");
selectGadget (AusgabeFenster, frageGadget (objekt));
disableGadgets (EingabeFenster,
LONGSET {NameID..MasseID, FarbeID+1..FarbeID+maxKoerper});
WindowToFront (AusgabeFenster);
ELSE
objekt := findeObjekt (EingabeFenster, SimuID);
aenderInfoSatz (objekt , " Mach weiter! ");
deselectGadget (EingabeFenster, frageGadget (objekt));
objekt := findeObjekt (AusgabeFenster, SimuID);
aenderInfoSatz (objekt , " Mach weiter! ");
deselectGadget (AusgabeFenster, frageGadget (objekt));
enableGadgets (EingabeFenster,
LONGSET {NameID..MasseID, FarbeID+1..FarbeID+maxKoerper});
Koerper[0] := Koerper[Planet];
erneuerObjekte (EingabeFenster, LONGSET {NameID..MasseID});
WindowToFront (EingabeFenster);
END
END StartStopAktion;
PROCEDURE KoerperAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
VAR alt :ObjektPtr;
neuPlanet :INTEGER;
BEGIN
IF frageObjektNr (objekt) # Planet+KoerperID THEN
alt := findeObjekt (EingabeFenster, Planet+KoerperID);
deselectGadget (EingabeFenster,
frageGadget (alt));
selectGadget (EingabeFenster, frageGadget (objekt));
IF NOT (rechnenAn) THEN
Koerper[0].Aktiv := Koerper[Planet].Aktiv;
Koerper[Planet] := Koerper[0]
END;
aenderInfoSatz (alt, Koerper[Planet].Name)
END;
neuPlanet := frageObjektNr (objekt)-KoerperID;
IF Koerper[Planet].Farbe # Koerper[neuPlanet].Farbe THEN
aenderInfoSatz ( findeObjekt (EingabeFenster,
Koerper[Planet].Farbe-3+FarbeID), " ");
aenderInfoSatz ( findeObjekt (EingabeFenster,
Koerper[neuPlanet].Farbe-3+FarbeID), " * ")
END;
IF (Planet = neuPlanet) AND (Koerper[Planet].Masse = 0.0)
AND Koerper[Planet].Aktiv THEN
Koerper[Planet].Aktiv := FALSE;
aenderInfoSatz ( findeObjekt (EingabeFenster, Planet+AktivID), " ")
END;
Planet := neuPlanet;
Koerper[0] := Koerper[Planet];
erneuerObjekte (EingabeFenster, LONGSET {NameID..MasseID})
END KoerperAktion;
PROCEDURE UrAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
VAR i :INTEGER;
Text :ARRAY [1..maxName+2] OF CHAR;
BEGIN
aenderInfoSatz ( findeObjekt (EingabeFenster,
Koerper[Planet].Farbe-3+FarbeID), " ");
deselectGadget (EingabeFenster,
frageGadget (findeObjekt (EingabeFenster, Planet+KoerperID)));
WerteEinstellen;
aenderInfoSatz ( findeObjekt (EingabeFenster,
Koerper[Planet].Farbe-3+FarbeID), " * ");
selectGadget (EingabeFenster,
frageGadget (findeObjekt (EingabeFenster, Planet+KoerperID)));
erneuerObjekte (EingabeFenster, LONGSET {NameID..ZoomID});
FOR i := 1 TO maxKoerper DO
aenderInfoSatz (findeObjekt (EingabeFenster, i+KoerperID), Koerper[i].Name);
IF Koerper[i].Aktiv THEN
aenderInfoSatz ( findeObjekt (EingabeFenster, AktivID+i), " * ")
ELSE
aenderInfoSatz ( findeObjekt (EingabeFenster, AktivID+i), " ")
END
END;
LoescheAusgabe
END UrAktion;
PROCEDURE AktivAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
VAR i :INTEGER;
BEGIN
i := frageObjektNr (objekt) - AktivID;
IF Koerper[i].Aktiv THEN
Koerper[i].Aktiv := FALSE;
aenderInfoSatz (objekt, " ")
ELSIF ((Planet = i) AND (Koerper[0].Masse # 0.0)) OR
((Planet # i) AND (Koerper[i].Masse # 0.0)) THEN
Koerper[i].Aktiv := TRUE;
aenderInfoSatz (objekt, " * ")
END
END AktivAktion;
PROCEDURE FarbAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
BEGIN
WITH Koerper[0] DO
IF Farbe # (frageObjektNr (objekt)+3 - FarbeID) THEN
aenderInfoSatz (findeObjekt (EingabeFenster, Farbe-3 + FarbeID), " ");
Koerper[0].Farbe := frageObjektNr (objekt)+3 - FarbeID;
aenderInfoSatz (objekt, " * ")
END
END
END FarbAktion;
PROCEDURE pruefeMasse ( objekt :ObjektPtr) :BOOLEAN;
BEGIN
WITH Koerper[0] DO
IF (Masse = 0.0) AND Koerper[Planet].Aktiv THEN
Koerper[Planet].Aktiv := FALSE;
aenderInfoSatz (findeObjekt (EingabeFenster, Planet+AktivID), " ")
END;
RETURN Masse >= 0.0
END
END pruefeMasse;
PROCEDURE pruefeZeit ( objekt :ObjektPtr) :BOOLEAN;
BEGIN
RETURN (t > 0.0)
END pruefeZeit;
PROCEDURE pruefeZoom ( objekt :ObjektPtr) :BOOLEAN;
BEGIN
IF (Zoom # altZoom) AND (Zoom > 0.0) THEN
LoescheAusgabe;
altZoom := Zoom
END;
RETURN (Zoom > 0.0)
END pruefeZoom;
PROCEDURE HochAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
VAR y :CARDINAL;
BEGIN
y := CARDINAL ((LONGCARD (frageVPosition (objekt)) *
LONGCARD (superHoehe - AusgabeFenster^.gzzHeight)) DIV
maxBody);
IF y # yAlt THEN
ScrollLayer (AusgabeFenster^.wLayer, 0, LONGINT (y)-LONGINT (yAlt));
yAlt := y
END
END HochAktion;
PROCEDURE BreitAktion ( Ereignis :ObjektEreignis;
objekt :ObjektPtr);
VAR x :CARDINAL;
BEGIN
x := CARDINAL ((LONGCARD (frageHPosition (objekt)) *
LONGCARD (superBreite-AusgabeFenster^.gzzWidth)) DIV
maxBody);
IF x # xAlt THEN
ScrollLayer (AusgabeFenster^.wLayer, LONGINT (x)-LONGINT (xAlt), 0);
xAlt := x
END
END BreitAktion;
PROCEDURE EingabeErzeugen;
VAR i :INTEGER;
Text :ARRAY [1..maxName+1] OF CHAR;
objekt :ObjektPtr;
BEGIN
UseWindow (EingabeFenster);
UseFont (Times18);
SetAPen (1);
Move ( 25,35); WriteString ("Himmelskörper");
Move (185,35); WriteString ("Aktiv");
setzeLinienFarbe (15,-1);
setzeRandFarbe (14, -1);
FOR i := 1 TO maxKoerper DO
setzeTextFarbe ( 1, 0);
erzeugeBooleanObjekt (EingabeFenster, 23,30+i*10, Koerper[i].Name,
i+KoerperID, melden, KoerperAktion);
IF i = Planet THEN
selectGadget (EingabeFenster,
frageGadget (findeObjekt (EingabeFenster, Planet+KoerperID)))
END;
setzeTextFarbe ( 1, 8);
IF Koerper[i].Masse # 0.0 THEN
Koerper[i].Aktiv := TRUE;
erzeugeBooleanObjekt (EingabeFenster, 196,30+i*10, " * ", i+AktivID,
melden, AktivAktion)
ELSE
erzeugeBooleanObjekt (EingabeFenster, 196,30+i*10, " ", i+AktivID,
melden, AktivAktion)
END
END;
setzeTextFarbe ( 1, 0);
erzeugeRealObjekt (EingabeFenster, 143,170, "Zeitdifferenz:", ZeitID, -120,0,
10,3, TRUE, pruefeZeit ,t);
erzeugeRealObjekt (EingabeFenster, 143,185, "Zoomfaktor: ", ZoomID, -120,0,
10,3, TRUE, pruefeZoom, Zoom);
erzeugeBooleanObjekt (EingabeFenster, 50,205, " Urzustand ", NeuID,
melden, UrAktion);
erzeugeBooleanObjekt (EingabeFenster, 50,215, " lösche Ausgabe ", LoeschenID,
melden, LoescheAktion);
erzeugeBooleanObjekt (EingabeFenster, 50,225, " Fang an! ", SimuID,
melden, StartStopAktion);
erzeugeRealObjekt (EingabeFenster, 490,170, "Masse:", MasseID, -184,0,
15,5, TRUE, pruefeMasse, Koerper[0].Masse);
erzeugeRealObjekt (EingabeFenster, 490,152, " z:", vID+2,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Geschwindigkeit.z);
erzeugeRealObjekt (EingabeFenster, 490,141, " y:", vID+1,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Geschwindigkeit.y);
erzeugeRealObjekt (EingabeFenster, 490,130, "Geschwindigkeit x:", vID ,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Geschwindigkeit.x);
erzeugeRealObjekt (EingabeFenster, 490,112, " z:", aID+2,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Beschleunigung.z);
erzeugeRealObjekt (EingabeFenster, 490,101, " y:", aID+1,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Beschleunigung.y);
erzeugeRealObjekt (EingabeFenster, 490, 90, "Beschleunigung x:", aID ,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Beschleunigung.x);
erzeugeRealObjekt (EingabeFenster, 490, 72, " z:",PosID+2,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Position.z);
erzeugeRealObjekt (EingabeFenster, 490, 61, " y:",PosID+1,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Position.y);
erzeugeRealObjekt (EingabeFenster, 490, 50, "Position x:",PosID ,-184,0,
15,5, TRUE, EingabeOk, Koerper[0].Position.x);
erzeugeTextObjekt (EingabeFenster, 370, 30, "Name:", NameID, -64,0,
maxName, maxName, EingabeOk, Koerper[0].Name);
Move (306, 220); UseFont (Topaz8);
WriteString ("Farbe:");
FOR i := 1 TO maxKoerper DO
setzeTextFarbe (i+3, 1);
setzeRandFarbe (14, -1);
IF Koerper[0].Farbe = i+3 THEN
erzeugeBooleanObjekt (EingabeFenster, 306+(i-1)*26,225, " * ",FarbeID+i,
melden, FarbAktion)
ELSE
erzeugeBooleanObjekt (EingabeFenster, 306+(i-1)*26,225, " ",FarbeID+i,
melden, FarbAktion)
END
END;
setzeTextFarbe (1, 0);
verbindeObjekte (EingabeFenster, NameID, -1, PosID, -1, -1);
verbindeObjekte (EingabeFenster, PosID, NameID, PosID+1, -1, -1);
verbindeObjekte (EingabeFenster, PosID+1, PosID, PosID+2, -1, -1);
verbindeObjekte (EingabeFenster, PosID+2, PosID+1, aID, -1, -1);
verbindeObjekte (EingabeFenster, aID, PosID+2, aID+1, -1, -1);
verbindeObjekte (EingabeFenster, aID+1, aID, aID+2, -1, -1);
verbindeObjekte (EingabeFenster, aID+2, aID+1, vID, -1, -1);
verbindeObjekte (EingabeFenster, vID, aID+2, vID+1, -1, -1);
verbindeObjekte (EingabeFenster, vID+1, vID, vID+2, -1, -1);
verbindeObjekte (EingabeFenster, vID+2, vID+1, MasseID, -1, -1);
verbindeObjekte (EingabeFenster, MasseID, vID+2, -1, -1, -1);
verbindeObjekte (EingabeFenster, ZeitID, -1, ZoomID, -1, -1);
verbindeObjekte (EingabeFenster, ZoomID, ZeitID, -1, -1, -1);
rechnenAn := FALSE;
setzeGadgetTyp (gzzGadget);
setzeAusrichtung ( GadgetFlagSet {YrelHoehe});
erzeugeBooleanObjekt (AusgabeFenster, 4,-8, " Fang an! ", SimuID,
melden, StartStopAktion);
setzeAusrichtung ( GadgetFlagSet {YrelHoehe, relBreite});
erzeugeHPropObjekt (AusgabeFenster, 134,-8, -153, 8,
maxBody DIV 2,
CARDINAL (maxBody * LONGCARD (AusgabeFenster^.gzzWidth) DIV
superBreite),
BreitID, wiederholen, BreitAktion);
setzeAusrichtung ( GadgetFlagSet {XrelBreite, relHoehe});
erzeugeVPropObjekt (AusgabeFenster, -16,11, 16,-21,
maxBody DIV 2,
CARDINAL (maxBody * LONGCARD (AusgabeFenster^.gzzHeight) DIV
superHoehe),
HochID, wiederholen, HochAktion);
setzeAusrichtung ( GadgetFlagSet {});
setzeGadgetTyp (0);
xAlt := (superBreite-AusgabeFenster^.gzzWidth) DIV 2;
yAlt := (superHoehe-AusgabeFenster^.gzzHeight) DIV 2;
ScrollLayer (AusgabeFenster^.wLayer, xAlt, yAlt);
END EingabeErzeugen;
(*----------------------------------------------------------------------------*)
PROCEDURE Zeichnen;
(*----------------------------------------------------------------------------*)
VAR i :INTEGER;
a,b :REAL;
BEGIN
FOR i := 1 TO maxKoerper DO
WITH Koerper[i] DO
IF Aktiv
THEN (*-- Zeichnen -------------------------------------------------------*)
a := (AltPosition.x / Zoom) * 2.0 + REAL (superBreite DIV 2);
b := AltPosition.y / Zoom + REAL (superHoehe DIV 2);
IF (a>0.0) AND (a<REAL(superBreite)) AND
(b>0.0) AND (b<REAL(superHoehe))
THEN SetAPen (Farbe);
WritePixel (INTEGER (a), INTEGER (b))
END; (* IF *)
a := (Position.x / Zoom) * 2.0 + REAL (superBreite DIV 2);
b := Position.y / Zoom + REAL (superHoehe DIV 2);
IF (a>0.0) AND (a<REAL(superBreite)) AND
(b>0.0) AND (b<REAL(superHoehe))
THEN SetAPen (8);
WritePixel (INTEGER (a), INTEGER (b))
END; (* IF *)
AltPosition := Position
END (* IF *)
END (* WITH Koerper[i] *)
END (* FOR i *)
END Zeichnen;
(*----------------------------------------------------------------------------*)
PROCEDURE Berechnung;
(*----------------------------------------------------------------------------*)
VAR Dx, Dy, Dz, D, D2, A :REAL;
K1, K2 :INTEGER;
Kollision :BOOLEAN;
Text :ARRAY [1..maxName+2] OF CHAR;
BEGIN
UseWindow (AusgabeFenster);
Kollision := FALSE;
K1 := 1;
WHILE K1 <= maxKoerper DO
IF Koerper[K1].Aktiv
THEN WITH Koerper[K1] DO
(*-- Beschleunigung berechnen ----------------------------------------*)
WITH Beschleunigung DO
x := 0.0;
y := 0.0;
z := 0.0;
END; (* WITH *)
K2 := 1;
WHILE K2 <= maxKoerper DO
IF (Koerper[K2].Aktiv) AND (K2 # K1)
THEN Dx := Koerper [K2].AltPosition.x - AltPosition.x;
Dy := Koerper [K2].AltPosition.y - AltPosition.y;
Dz := Koerper [K2].AltPosition.z - AltPosition.z;
D2 := ABS (Dx*Dx + Dy*Dy + Dz*Dz);
D := sqrt (D2);
IF D < 1.0
THEN Name := "Gesteinsbrocken";
Masse := Masse + Koerper[K2].Masse;
Geschwindigkeit.x := Geschwindigkeit.x +
Koerper[K2].Geschwindigkeit.x;
Geschwindigkeit.y := Geschwindigkeit.y +
Koerper[K2].Geschwindigkeit.y;
Geschwindigkeit.z := Geschwindigkeit.z +
Koerper[K2].Geschwindigkeit.z;
aenderInfoSatz ( findeObjekt (EingabeFenster,
KoerperID+K1), Name);
Koerper[K2].Name := '';
Koerper[K2].Masse := 0.0;
Koerper[K2].Aktiv := FALSE;
aenderInfoSatz ( findeObjekt (EingabeFenster,
KoerperID + K2), Koerper[K2].Name);
aenderInfoSatz ( findeObjekt (EingabeFenster,
AktivID + K2) , " ");
IF (Planet = K1) OR (Planet = K2)
THEN Koerper[0] := Koerper[Planet];
erneuerObjekte (EingabeFenster,
LONGSET {NameID..MasseID})
END; (* IF *)
Kollision := TRUE;
K1 := maxKoerper;
K2 := maxKoerper
ELSE A := g * Koerper[K2].Masse / (D2 * D);
WITH Beschleunigung DO
x := x + A * Dx;
y := y + A * Dy;
z := z + A * Dz
END (* WITH *)
END (* IF *)
END; (* IF *)
INC (K2)
END; (* WHILE *)
(*-- Geschwindigkeit berechnen --------------------------------------*)
WITH Geschwindigkeit DO
x := x + Beschleunigung.x * t;
y := y + Beschleunigung.y * t;
z := z + Beschleunigung.z * t
END; (* WITH Geschwindigkeit *)
(*-- Position berechnen ---------------------------------------------*)
WITH Position DO
x := AltPosition.x + Geschwindigkeit.x * t;
y := AltPosition.y + Geschwindigkeit.y * t;
z := AltPosition.z + Geschwindigkeit.z * t;
END (* WITH Position *)
END (* WITH Koerper[K1] *)
END; (* IF *)
INC (K1)
END; (* WHILE K1 *)
IF NOT Kollision
THEN Zeichnen
END (* IF *)
END Berechnung;
PROCEDURE sieheEreignisse;
VAR Ende, vergroessernAn :BOOLEAN;
Signal :LONGSET;
NachrichtPtr :IntuiMessagePtr;
Nachricht :IntuiMessage;
PROCEDURE bearbeiteNachricht ( Fenster :WindowPtr;
VAR Nachricht :IntuiMessage);
VAR objekt :ObjektPtr;
BEGIN
verarbeiteNachricht (Fenster, Nachricht);
WITH Nachricht DO
IF sizeVerify IN class THEN
vergroessernAn := TRUE
ELSIF newSize IN class THEN
vergroessernAn := FALSE;
objekt := findeObjekt (AusgabeFenster, BreitID);
setzeHPosition (objekt, frageHPosition (objekt),
CARDINAL (maxBody * LONGCARD (AusgabeFenster^.gzzWidth) DIV
superBreite));
objekt := findeObjekt (AusgabeFenster, HochID);
setzeVPosition (objekt, frageVPosition (objekt),
CARDINAL (maxBody * LONGCARD (AusgabeFenster^.gzzHeight) DIV
superHoehe));
HochAktion (Start, findeObjekt (AusgabeFenster, HochID));
BreitAktion (Start, findeObjekt (AusgabeFenster, BreitID))
ELSIF closeWindow IN class THEN
Ende := TRUE
ELSE
END
END
END bearbeiteNachricht;
(* sieheEreignisse *)
BEGIN
UseWindow (AusgabeFenster);
Ende := FALSE;
vergroessernAn := FALSE;
WHILE NOT Ende DO
IF rechnenAn THEN
IF NOT vergroessernAn THEN
Berechnung
END
ELSE
Signal := Wait (LONGSET {EingabeFenster^.userPort^.sigBit,
AusgabeFenster^.userPort^.sigBit})
END;
REPEAT
NachrichtPtr := GetMsg (EingabeFenster^.userPort);
IF NachrichtPtr # NIL THEN
Nachricht := NachrichtPtr^;
ReplyMsg (NachrichtPtr);
bearbeiteNachricht (EingabeFenster, Nachricht)
END
UNTIL NachrichtPtr = NIL;
REPEAT
NachrichtPtr := GetMsg (AusgabeFenster^.userPort);
IF NachrichtPtr # NIL THEN
Nachricht := NachrichtPtr^;
ReplyMsg (NachrichtPtr);
bearbeiteNachricht (AusgabeFenster, Nachricht)
END
UNTIL NachrichtPtr = NIL
END
END sieheEreignisse;
(* HP *)
BEGIN
SystemAnpassen;
WerteEinstellen;
EingabeErzeugen;
sieheEreignisse
END SternSimulation.